﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace ExcelDna.Integration.Rtd
{
    [ComVisible(true)]
    internal class ExcelObserverRtdServer : ExcelRtdServer
    {
        Dictionary<Topic, Guid> _topicGuids = new Dictionary<Topic, Guid>();

        protected override object ConnectData(Topic topic, IList<string> topicInfo, ref bool newValues)
        {
            // Retrieve and store the GUID from the topic's first info string - used to hook up to the Async state
            Guid id = new Guid(topicInfo[0]);
            _topicGuids[topic] = id;

            // Create a new ExcelRtdObserver, for the Topic, which will listen to the Observable
            // (Internally also set initial value - #N/A for now)
            ExcelRtdObserver rtdObserver = new ExcelRtdObserver(topic);
            // ... and subscribe it
            AsyncObservableImpl.ConnectObserver(id, rtdObserver);

            // Return something: #N/A for now. Not currently used.
            // TODO: Allow customize?
            return ExcelErrorUtil.ToComError(ExcelError.ExcelErrorNA);
        }

        protected override void DisconnectData(Topic topic)
        {
            // Retrieve the GUID from the topic's first info string - used to hook up to the Async state
            Guid id = _topicGuids[topic];

            // ... and unsubscribe it
            AsyncObservableImpl.DisconnectObserver(id);
            _topicGuids.Remove(topic);
        }

        // This makes sure the hook up with the registration-free RTD loading is in place.
        // For a user RTD server the add-in loading would ensure this, but not for this class since it is declared inside Excel-DNA.
        static bool _isRegistered = false;
        internal static void EnsureRtdServerRegistered()
        {
            if (!_isRegistered)
            {
                RtdRegistration.RegisterRtdServerTypes(new Type[] { typeof(ExcelObserverRtdServer) });
            }
            _isRegistered = true;
        }
    }
}
